ひとりNavigation API Advent Calendar 24日目
https://gyazo.com/6fcdab63e97f318c2514d9aac6b9c035
Reactだと<ViewTransition>、Vue Routerだと<transition>コンポーネントがあってその内部でトランジション効果をつけられるようになっていたりする https://gyazo.com/2e4d72ea5d19c29d576fc814444cf5ea
https://scrapbox.io/files/694b83a399c35468d46d76db.mov
変更点
intercept()内にstartViewTransitionを指定する
code:js
// View Transitions API がサポートされている場合
if (document.startViewTransition) {
const transition = document.startViewTransition(() => {
this.handleRoute(url.pathname);
});
await transition.finished;
} else {
// サポートされていない場合は即座に更新
this.handleRoute(url.pathname);
}
ページの戻る・進む押下時の判定処理を入れる
code:js
let lastIndex = navigation.currentEntry.index;
navigation.addEventListener('currententrychange', (event) => {
const currentIndex = navigation.currentEntry.index;
if (currentIndex < lastIndex) { // 戻るを押下したとき
document.documentElement.dataset.direction = 'back';
} else if (currentIndex > lastIndex) { // 進むを押下したとき
document.documentElement.dataset.direction = 'forward';
}
lastIndex = currentIndex;
});
code:css
padding: 2rem;
view-transition-name: page-content; /* コンテンツ領域のみがアニメーションするように指定 */
}
code:css
/* --- View Transitions API Animations --- */
::view-transition-old(page-content),
::view-transition-new(page-content) {
animation-duration: 0.4s;
animation-timing-function: ease-in-out;
animation-fill-mode: both;
mix-blend-mode: normal; /* 重要: ページが透けて重なるのを防ぐ */
}
animation-name: slide-out-to-left;
}
animation-name: slide-in-from-right;
}
animation-name: slide-out-to-right;
z-index: 1;
}
animation-name: slide-in-from-left;
z-index: 2;
}
/* キーフレーム定義 */
@keyframes slide-out-to-left {
from { transform: translateX(0); }
to { transform: translateX(-100%); }
}
@keyframes slide-in-from-right {
from { transform: translateX(100%); }
to { transform: translateX(0); }
}
@keyframes slide-out-to-right {
from { transform: translateX(0); }
to { transform: translateX(100%); }
}
@keyframes slide-in-from-left {
from { transform: translateX(-100%); }
to { transform: translateX(0); }
}
参考記事
仕様